package com.jia.thumps.service.impl;

import com.jia.thumps.service.FileService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author jia
 */
@Service("fileService")
public class FileServiceImpl implements FileService {

    // 默认一片是 5MB
    int partSize = 5 * 1024 * 1024;

    public static String dir = "statistics-service\\src\\main\\java\\com\\jia\\statistics\\file";

    @Override
    public String uploadFile(MultipartFile file) {
        if (Objects.isNull(file)) {
            throw new RuntimeException("file cannot be null");
        }
        long size = file.getSize();
        Path path = Paths.get(dir, file.getOriginalFilename());
        try {
            if (size < partSize) {
                file.transferTo(path);
                Files.copy(file.getInputStream(), path);
            } else {
                splitFile(file);
            }
            return file.getName();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void splitFile(MultipartFile file) {
        try (InputStream inputStream = file.getInputStream()) {
            long size = file.getSize();
            long partCount = size / partSize + (size % partSize == 0 ? 0 : 1);
            for (long i = 0; i < partCount; i++) {
                Path partPath = Paths.get(dir, file.getOriginalFilename() + "_" + i);
                byte[] bytes = new byte[partSize];
                try (OutputStream outputStream = Files.newOutputStream(partPath)) {
                    int read = inputStream.read(bytes);
                    outputStream.write(bytes, 0, read);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public String mergeFile(String fileId) {
        Path path = Paths.get(dir);
        List<String> fileChild = new ArrayList<>();
        try {
            Files.walk(path).forEach(file -> {
                if (file.getFileName().toString().startsWith(fileId)) {
                    fileChild.add(file.getFileName().toString());
                }
            });
            Path filePath = Paths.get(dir, fileId);
            OutputStream outputStream = Files.newOutputStream(filePath);
            for (int i = 0; i < fileChild.size(); i++) {
                Files.copy(Paths.get(dir, fileId + "_" + i), outputStream);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return fileId;
    }

    @Override
    public String downloadFile(String fileId, HttpServletRequest request, HttpServletResponse response) {
        try {
            Path path = Paths.get(dir, fileId);
            OutputStream outputStream = response.getOutputStream();
            response.setContentType("application/x-download");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileId);
            Files.copy(path, outputStream);
            outputStream.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return fileId;
    }


}
